Function references

Hi,
I have some problem with DXL. I would like to put functions into skip list and next pick them up in the for loop.
I was trying to do something similar to C function pointers, but can't make it work.
Maybe someone have a clue what I do wrong or how else should I do it?
 

// Functions sack
Skip slFunctions = createString()
 
// Put some functions to sack
void fun1() { print "fun1\n" }
put(slFunctions, "fun1", fun1)
 
void fun2() { print "fun2\n" }
put(slFunctions, "fun2", fun2)
 
// Main code
// What declaration should i use?
void (&func)()
 
for func in slFunctions do {
    func()
}

 


/Jarek

 


SystemAdmin - Fri Oct 30 05:59:17 EDT 2009

Re: Function references
llandale - Fri Oct 30 13:19:33 EDT 2009

Clever use of the 'addr_' function, that converts the parameter to an address and assigns it to whatever you want. Just now made the attached work and should perhaps get you going.

void   f1(string Label)
{  print Label "  In f1\n"
}
 
void    f2(string Label)
{  print Label "  In f2\n"
}
 
void   CallFunct(void funct(string), string Label)
{  funct(Label)
}
 
Skip skp = create  // KEY addr_ function, DATA 'string' name
put(skp, f1, "FF1")
put(skp, f2, "AA2")
 
string Dat
 
for Dat in skp do
{  CallFunct(addr_(int key skp), Dat)
}


 


Expect lots of exception violations as you try to line up the addr_ of something with its correct retrieved type.

Maybe someone will chime in here and let us know how to use the DATA part of the Skip to house the address of the function. That is, define a 'function' variable.

 

 

 

  • Louie

 

 

Re: Function references
SystemAdmin - Mon Nov 02 04:49:16 EST 2009

According to what you replaied, I've maneged to work some code which uses functions as data parameter.
The important thing is the dummy function variable, which is used to store the addres of the function.
It looks like it can be almost anything (prefered pointer).
 

// Functions sack
Skip slFunctions = createString()
 
// Put some functions to sack
bool fun1(string s) { 
    print "In fun1: " s "\n" ; 
        return true 
}
put(slFunctions, "fun1_name", fun1)
 
bool fun2(string s) { 
        print "In fun2: " s "\n" ; 
        return false
}
put(slFunctions, "fun2_name", fun2)
 
// Function calling wrapper
bool callFunc(bool func(string), string s) {
        return func(s)
}
 
// Main code
void *func // dummy pointer variable
for func in slFunctions do {
        bool rval = callFunc(addr_(func), (string key slFunctions))
        print "rval = " rval "\n"
}


DXL output:

 

In fun1: fun1_name
rval = true
In fun2: fun2_name
rval = false

 


Nevertheless it works, any second thoughts will be appreciated.

/Jarek

 

 

 

 

 

Re: Function references
llandale - Mon Nov 02 09:57:37 EST 2009

SystemAdmin - Mon Nov 02 04:49:16 EST 2009

According to what you replaied, I've maneged to work some code which uses functions as data parameter.
The important thing is the dummy function variable, which is used to store the addres of the function.
It looks like it can be almost anything (prefered pointer).
 

// Functions sack
Skip slFunctions = createString()
 
// Put some functions to sack
bool fun1(string s) { 
    print "In fun1: " s "\n" ; 
        return true 
}
put(slFunctions, "fun1_name", fun1)
 
bool fun2(string s) { 
        print "In fun2: " s "\n" ; 
        return false
}
put(slFunctions, "fun2_name", fun2)
 
// Function calling wrapper
bool callFunc(bool func(string), string s) {
        return func(s)
}
 
// Main code
void *func // dummy pointer variable
for func in slFunctions do {
        bool rval = callFunc(addr_(func), (string key slFunctions))
        print "rval = " rval "\n"
}


DXL output:

 

In fun1: fun1_name
rval = true
In fun2: fun2_name
rval = false

 


Nevertheless it works, any second thoughts will be appreciated.

/Jarek

 

 

 

 

 

Other than for the sake of being clever, I wonder why we would WANT to put functions in Skips and call them like this. Seems to be better ..err.. easier to write, debug, and understand later, if we just created some big function:

bool   CallIt(int FunctNum, string Parameter)
{
    if     (FunctNum == 0)  return(f0(Parameter))
    elseif (FunctNum == 1)  return(f1(Parameter))
    elseif (FunctNum == 2)  return(f2(Parameter))
    else   log error, return(false)
}


Software should be:
[1] Understandable
[2] Effective
[3] Maintainable
[4] Efficient
...
20 Elegant
...
99 Impressive.

 

 

  • Louie


Well, unless you are trying to score, in which case move 'impressive' up.

 

 

Re: Function references
SystemAdmin - Mon Nov 02 10:19:12 EST 2009

llandale - Mon Nov 02 09:57:37 EST 2009

Other than for the sake of being clever, I wonder why we would WANT to put functions in Skips and call them like this. Seems to be better ..err.. easier to write, debug, and understand later, if we just created some big function:

bool   CallIt(int FunctNum, string Parameter)
{
    if     (FunctNum == 0)  return(f0(Parameter))
    elseif (FunctNum == 1)  return(f1(Parameter))
    elseif (FunctNum == 2)  return(f2(Parameter))
    else   log error, return(false)
}


Software should be:
[1] Understandable
[2] Effective
[3] Maintainable
[4] Efficient
...
20 Elegant
...
99 Impressive.

 

 

  • Louie


Well, unless you are trying to score, in which case move 'impressive' up.

 

 

Heh,

In fact there will be many those small functions.
What I'm doing is a small framework for testing.
So you can have single skeleton for different sets of test cases.
So you can add new ones quickly and easily as a pie ;]
Then you get a list of results if objects passes particular test or not.

/Jarek

Re: Function references
Mathias Mamsch - Wed Nov 04 09:29:01 EST 2009

SystemAdmin - Mon Nov 02 10:19:12 EST 2009
Heh,

In fact there will be many those small functions.
What I'm doing is a small framework for testing.
So you can have single skeleton for different sets of test cases.
So you can add new ones quickly and easily as a pie ;]
Then you get a list of results if objects passes particular test or not.

/Jarek

I guess the DXL way to go about this is using a static test function definition, but using a DXLObject for the parameters

Maybe something like the below ...

Regards, Mathias
 

Skip testCases = create()
 
void addTestFunction ( string testName, void testfunc (bool&) ) {
   int ad = (addr_ testfunc) int
   put (testCases, ad, testName)
}
 
bool runTest ( void *func(bool&) ) {  
    int x = addr_ func
        bool res = false; 
        func (res); 
        return res 
}
 
 
Skip runTestSuite () {
    string name
    Skip results = createString() 
 
    for name in testCases do {
                int ad = (key testCases) int 
                bool res = runTest addr_ ad
           put (results, name, res )
    }
 
    return results
}
 
void test1 (bool &result) {
   result = true;
}
 
void test2 (bool &result) {
   result = false;
}
 
addTestFunction ("Good Test", test1)
addTestFunction ("Bad Test", test2) 
 
Skip result = runTestSuite()
 
bool res 
string testName
 
for res in result do {
        testName = (key result) string
        print "Test: " testName " --> " (res ? "Passed" : "FAIL") "\n"
}